package com.ruoyi.web.controller.edh;


import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.app.models.AlipayTradeAppPayResponse;

import com.egzosn.pay.ali.bean.AliTransactionType;
import com.egzosn.pay.common.bean.PayMessage;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.http.UriVariables;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.OrderException;
import com.ruoyi.common.exception.PayException;
import com.ruoyi.common.pay.alipay.AliPayInitConFig;
import com.ruoyi.common.pay.alipay.QueryOrder;
import com.ruoyi.edh.domain.bo.OrderPayBo;
import com.ruoyi.edh.service.IEdhMasterOrderAliPayService;
import com.ruoyi.edh.service.IEdhOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/edh")
@Api("主订单支付宝付款接口")
public class EdhAilPayOrderController extends AliPayInitConFig {
    @Autowired
    private IEdhMasterOrderAliPayService iEdhMasterOrderAliPayService;
    @Autowired
    private IEdhOrderService edhOrderService;

    /**
     * @param masterOrderNo 主订单id
     * @description: 主订单支付接口, 支付宝
     * @return: String 返回支付宝的电脑扫码付款页面
     * @author: 梁东宸
     * @time: 2020/10/14 3:10 下午
     */
    @RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8")
    @ApiOperation("主订单支付宝支付接口")
    public String masterOrderAliPay(String masterOrderNo) {
        PayOrder payOrder = iEdhMasterOrderAliPayService.masterOrderAliPay(masterOrderNo);
        return service.toPay(payOrder);
    }

    /**
     * App支付
     *
     * @return 支付预订单信息
     */
    @RequestMapping("/appPay1")
    @ApiOperation("支付接口")
    public Map<String, Object> app(String masterOrderNo) {
        Map<String, Object> data = new HashMap<>(10);

        PayOrder payOrder = null;
        data.put("code", 200);
        try {
            payOrder = iEdhMasterOrderAliPayService.masterOrderAliPay(masterOrderNo);
        } catch (Exception e) {
            data.put("code", 500);
            e.printStackTrace();
        }
        //App支付
        payOrder.setTransactionType(AliTransactionType.APP);
        data.put("orderInfo", UriVariables.getMapToParameters(service.app(payOrder)));
        System.out.println(data.get("orderInfo"));
        return data;
    }

    /**
     * @Author: 周爱鸿
     * @Description: app支付预付单
     * @CreateDate: 2020/11/13 10:00
     */
    @RequestMapping("/appPay")
    @ApiOperation("支付接口")
    public Map<String, Object> appPay(String masterOrderNo) {
        // 1. 设置参数（全局只需设置一次）
        Factory.setOptions(getOptions());
        HashMap<String, Object> result = new HashMap<String, Object>();

        AlipayTradeAppPayResponse pay = null;
        try {
            // 2. 发起API调用（以创建当面付收款二维码为例）
            pay = iEdhMasterOrderAliPayService.masterOrderAliPay1(masterOrderNo);
            System.out.println(pay.getBody());
            // 3. 处理响应或异常
            if (ResponseChecker.success(pay)) {
                System.out.println("调用成功");
            } else {
                System.err.println("调用失败，原因：" + pay.getBody());
            }
        } catch (Exception e) {
            System.err.println("调用遭遇异常，原因：" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        result.put("code", 200);
        result.put("orderInfo", pay.getBody());
        return result;
    }

    /**
     * 支付回调地址 方式一
     * <p>
     * 方式二，{@link #(HttpServletRequest)} 是属于简化方式， 试用与简单的业务场景
     *
     * @param request 请求
     * @return 返回对应的响应码F
     * @throws IOException IOException
     * @see #(HttpServletRequest)
     */
    @Deprecated
    @RequestMapping(value = "/payOrder1")
    public String payBackBefore1(HttpServletRequest request) throws IOException, ParseException {

        //获取支付方返回的对应参数
        Map<String, Object> params = service.getParameter2Map(request.getParameterMap(), request.getInputStream());
        if (null == params) {
            return service.getPayOutMessage("fail", "失败").toMessage();
        }

        //校验
        if (service.verify(params)) {
            //创建支付业务对象
            OrderPayBo orderPayBo = new OrderPayBo();
            String outTradeNo = params.get("out_trade_no").toString();
            orderPayBo.setOutTradeNo(outTradeNo);
            orderPayBo.setTradeNo(params.get("trade_no").toString());
            orderPayBo.setSellerId(params.get("seller_id").toString());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            orderPayBo.setTimestamp(sdf.parse(String.valueOf(params.get("gmt_create"))));
            orderPayBo.setPaymentType("0");
            orderPayBo.setOriginalPrice(new BigDecimal(String.valueOf(params.get("total_amount"))));
            try {
                Boolean aBoolean = iEdhMasterOrderAliPayService.payMentSuccess(orderPayBo);
                if (!aBoolean) {
                    //把付款状态修改为付款失败
                    edhOrderService.updateOrderStatusFailure(outTradeNo);
                    return service.getPayOutMessage("fail", "订单更新失败").toMessage();
                }
            } catch (PayException e) {
                edhOrderService.updateOrderStatusFailure(outTradeNo);
                return service.getPayOutMessage("fail", e.getMessage()).toMessage();
            } catch (OrderException e) {
                edhOrderService.updateOrderStatusFailure(outTradeNo);
                return service.getPayOutMessage("fail", e.getMessage()).toMessage();
            }
            PayMessage payMessage = new PayMessage();
            payMessage.setPayType("支付宝");
            payMessage.setMsgType("支付成功");
            String message = service.successPayOutMessage(payMessage).toMessage();
            return message;
        }
        return service.getPayOutMessage("fail", "失败").toMessage();
    }

    /**
     * @Description: 支付宝退款
     */
    public static void main1(String[] args) {
        try {
            Factory.setOptions(new EdhAilPayOrderController().getOptions());
            Factory.Payment.Common().refund("ZD160549669500494", "0.01");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Author: 周爱鸿
     * @Description: 支付回调地址
     * @CreateDate: 2020/11/13 10:10
     */
    @Deprecated
    @RequestMapping(value = "/payOrder")
    public String payBackBefore(HttpServletRequest request) throws IOException, ParseException {

        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String> params = new HashMap<String, String>(40);
        for (HashMap.Entry entry : parameterMap.entrySet()) {
            params.put(String.valueOf(entry.getKey()), request.getParameter(String.valueOf(entry.getKey())));
        }
        // 不验证支付签名
    /*    Boolean result = false;
        try {
             result = Factory.Payment.Common().verifyNotify(params);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        //校验  成功的话执行逻辑
        if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
            //创建支付业务对象
            OrderPayBo orderPayBo = new OrderPayBo();
            String outTradeNo = params.get("out_trade_no").toString();
            orderPayBo.setOutTradeNo(outTradeNo);
            orderPayBo.setTradeNo(params.get("trade_no").toString());
            orderPayBo.setSellerId(params.get("seller_id").toString());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            orderPayBo.setTimestamp(sdf.parse(String.valueOf(params.get("gmt_create"))));
            orderPayBo.setPaymentType("0");
            orderPayBo.setOriginalPrice(new BigDecimal(String.valueOf(params.get("total_amount"))));
            try {
                Boolean aBoolean = iEdhMasterOrderAliPayService.payMentSuccess(orderPayBo);
                if (!aBoolean) {
                    //把付款状态修改为付款失败
                    edhOrderService.updateOrderStatusFailure(outTradeNo);
                    return service.getPayOutMessage("fail", "订单更新失败").toMessage();
                }
            } catch (PayException e) {
                edhOrderService.updateOrderStatusFailure(outTradeNo);
                return service.getPayOutMessage("fail", e.getMessage()).toMessage();
            } catch (OrderException e) {
                edhOrderService.updateOrderStatusFailure(outTradeNo);
                return service.getPayOutMessage("fail", e.getMessage()).toMessage();
            }
            PayMessage payMessage = new PayMessage();
            payMessage.setPayType("支付宝");
            payMessage.setMsgType("支付成功");
            return service.successPayOutMessage(payMessage).toMessage();
        }
        return service.getPayOutMessage("fail", "失败").toMessage();
    }

    /**
     * 查询
     *
     * @param order 订单的请求体
     * @return 返回查询回来的结果集，支付方原值返回
     */
    @RequestMapping("query")
    public Map<String, Object> query(QueryOrder order) {
        return service.query(order.getTradeNo(), order.getOutTradeNo());
    }


    private Config getOptions() {
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipay.com";
        config.signType = "RSA2";

        config.appId = "2021001163628765";

        // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
        config.merchantPrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCl43NEh8XEPXpRcV4W+QKww5Ox2I6E+toMmyWUhX7BFNDkNNtFJWb96t185D8KaWgVjiiLj9Jwzs1NzoM57jdIcmrdIcatelv2a509GpQLoXZEwowgV+aCAi1yBGsjQZkFP9kFBaG6XNkkqDrDkpVY3u0pXpDDE1UxLWuCsZtCeEHyVOCNAxxlgi8oNRqA5nWLWFfyHy9MMriE6+4SnNmN1XZVk1l8qx/YZN2YzHRNK97/Jin4hD7JK09SucHtuTQ/Qh8nzDEFWXe6A1Pq5B09IM+ANafO3wW1Vxuoi01zrcEZ2AHfu2N1hG+vkT5xLJ2y7LQD3pj1cN9HpIDCfBmVAgMBAAECggEAVIj8835Q/LjrfVdNQF2yzktMF4Qo1IFU3rmtQ+tndZNbBAAfgTQXMOwf5IYXzgF7BgkEhmJLNitcmfrUCpBnYabU6E1PBpZlCMU8Qqgpq2ejclTFvbGtiLD9Ya34vuWtyewIdrOw/9xS14hXMdSgAMLRjpRfJtnSPxZLRDWnzg3QutvppdKPlD0JA+t6Noy9dIpiFDoeE3a4Q4RHUWyNk6qrNSNqtYyo6SYdgIek0abKrAeVxKmwXTCyX+Z+7Pvk4Tb2d9JVJoYqLUuKoMTOmdEft9AKt86CBLnz6b4XhFmQArxtxlnHxnQ9JSp5bdU2KWm3Lx+RHasVb50vaaAPAQKBgQDpb3OfPaOFA0ehkuJJxhjJgaHZb++iDGIFmCx10Tg3CzmNE0D3J2pg8gwOtkd2dvk7cTBTzPAdq3hghVQp3Q/A22afwieTJKP28ZG6I2QaW8xuIdLym1K8KsJFjkCF2RxxmalwAJNG/CMzbkkz/IjoiZvJ5uMmMKC0U7KSG2KE1QKBgQC17H73S52jrD2f+wIk4zFKfnz56ohkFPO9R2TxcHt+Lq/RrpE156SjG06CMhW1+rfzzABybzD2X/kisTZajfgLcmw8xXoU89rKJvuX1HV1/HGwRsFPQsrsGUuWxCQfDfIsyDHQ5eHzALQ3SOViE3QBlIpBJZ2F2JiOB623zvyhwQKBgQC6dSepvpZqnKAO00ClJPKPolghUmPa0IFLbq20vhVlAjZKFWMDCBzUqwIujjKu0YFqlZLAnSX+zQQuNNFxTv5SUe27Fl5+DfpaOcLpJ3PCCilUnvfciWygmJbs8B9hynYJ12+b4xnAzY1ge2tFdyX0eFZUA3TVAGqdH223fuBGsQKBgCDLXx/pK6OjmwBJ2VsY8XvCTXknxCp2dHG8ev/jDP/0HpGn7FlRRqZ4d7CUosFJTvvN3I7EaIkhR+HvHCM60GoP2F8kIhvA0cH7QQNfs0Tvmvbx6ksFeVsSPEQTW4eVlgBonkJQDmklyVbl9yO06gaW5k1UII9OOkHwNGqcD4KBAoGBAK3qRDKKyotQthN/tHEHLUqhnvDv6LJ30Z1ZK8E23vfAxIDSzWyL7Af0TSOpEHkuIzUoiHfv+vPy165w0astror7fwnnEzyyO/MttK1Y0ozz+zSakFUy2EYRQWVgR46LMbiCbTJJM8SSPUpJLJOpKRbUXF9sLbvnEn64xYPP/k77";

        //注：证书文件路径支持设置为文件系统中的路径或CLASS_PATH中的路径，优先从文件系统中加载，加载失败后会继续尝试从CLASS_PATH中加载
        //config.merchantCertPath = "<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->";
        //config.alipayCertPath = "<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->";
        //config.alipayRootCertPath = "<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt -->";

        //注：如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
        config.alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApeNzRIfFxD16UXFeFvkCsMOTsdiOhPraDJsllIV+wRTQ5DTbRSVm/erdfOQ/CmloFY4oi4/ScM7NTc6DOe43SHJq3SHGrXpb9mudPRqUC6F2RMKMIFfmggItcgRrI0GZBT/ZBQWhulzZJKg6w5KVWN7tKV6QwxNVMS1rgrGbQnhB8lTgjQMcZYIvKDUagOZ1i1hX8h8vTDK4hOvuEpzZjdV2VZNZfKsf2GTdmMx0TSve/yYp+IQ+yStPUrnB7bk0P0IfJ8wxBVl3ugNT6uQdPSDPgDWnzt8FtVcbqItNc63BGdgB37tjdYRvr5E+cSydsuy0A96Y9XDfR6SAwnwZlQIDAQAB";

        //可设置异步通知接收服务地址（可选）
        config.notifyUrl = "http://easybuy.yidingh.com:9092/edh/payOrder";

        //可设置AES密钥，调用AES加解密相关接口时需要（可选）
        //config.encryptKey = "<-- 请填写您的AES密钥，例如：aa4BtZ4tspm2wnXLb1ThQA== -->";

        return config;
    }
}
